﻿using An_Im.Extension.Contract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PPT = Microsoft.Office.Interop.PowerPoint;
namespace An_Im.QuickPPT
{




    public static class AddInMethods
    {
        #region 创建图形相关
        /// <summary>
        /// 创建无边框的矩形对象。
        /// </summary>
        /// <param name="app"></param>
        public static void CreateRectangleWithoutLine(PPT.Application app, IList<ParaNameValuePair> paralist)
        {
            CreateShapeWithoutLine(app, Microsoft.Office.Core.MsoAutoShapeType.msoShapeRectangle);
        }

        /// <summary>
        /// 创建无边框的椭圆对象。
        /// </summary>
        /// <param name="app"></param>
        public static void CreateOvalWithoutLine(PPT.Application app, IList<ParaNameValuePair> paralist)
        {
            CreateShapeWithoutLine(app, Microsoft.Office.Core.MsoAutoShapeType.msoShapeOval);
        }

        /// <summary>
        /// 创建无边框的圆角矩形对象。
        /// </summary>
        /// <param name="app"></param>
        public static void CreateRoundedRectangleWithoutLine(PPT.Application app, IList<ParaNameValuePair> paralist)
        {
            CreateShapeWithoutLine(app, Microsoft.Office.Core.MsoAutoShapeType.msoShapeRoundedRectangle);
        }



        /// <summary>
        /// 创建无边框的图形对象。
        /// </summary>
        /// <param name="app">根对象</param>
        /// <param name="autoShapeType">类型</param>
        /// <returns></returns>
        public static PPT.Shape CreateShapeWithoutLine(PPT.Application app, Microsoft.Office.Core.MsoAutoShapeType autoShapeType = Microsoft.Office.Core.MsoAutoShapeType.msoShapeRectangle)
        {
            var pres = app.ActivePresentation;
            var slideRange = GetCurrentSlideRange(app);
            var shapeRange = GetCurrentShapeRange(app);
            if (slideRange == null) return null;

            var height = 0f;
            var width = 0f;
            var left = 0f;
            var top = 0f;
            if (shapeRange != null) // 与当前首个图形一致。
            {
                var cshp = shapeRange[1];
                height = cshp.Height;
                width = cshp.Width;
                left = cshp.Left;
                top = cshp.Top;
            }
            else // 与当前幻灯片一致。
            {
                // var csld = slideRange[1];
                //width = GetPresentationWidth(pres);
                //height = GetPresentationHeight(pres);
                width = 50;
                height = 50;
                left = 0;
                top = 0;
            }

            var newshp = slideRange[1].Shapes.AddShape(autoShapeType, left, top, width, height);
            newshp.Line.Visible = Microsoft.Office.Core.MsoTriState.msoFalse;
            return newshp;
        }


        #endregion

        #region 对齐
        /// <summary>
        /// 默认横向对齐。
        /// </summary>
        /// <param name="app"></param>
        public static void AliagnShapeRangeHorizontal(PPT.Application app,IList<ParaNameValuePair> paralist)
        {
            AliagnShapeRange(app, true, false, false);
        }

        /// <summary>
        /// 默认纵向对齐。
        /// </summary>
        /// <param name="app"></param>
        public static void AliagnShapeRangeVertical(PPT.Application app,IList<ParaNameValuePair> paralist)
        {
            AliagnShapeRange(app, false, true, false);
        }

        /// <summary>
        /// 智能横向对齐。
        /// </summary>
        /// <param name="app"></param>
        public static void AliagnShapeRangeHorizontalSmart(PPT.Application app, IList<ParaNameValuePair> paralist)
        {
            AliagnShapeRange(app, true, false, true);
        }

        /// <summary>
        /// 智能纵向对齐。
        /// </summary>
        /// <param name="app"></param>
        public static void AliagnShapeRangeVerticalSmart(PPT.Application app, IList<ParaNameValuePair> paralist)
        {
            AliagnShapeRange(app, false, true, true);
        }



        /// <summary>
        /// 对齐图形位置。
        /// </summary>
        /// <param name="app"></param>
        /// <param name="isHori"></param>
        /// <param name="isVert"></param>
        /// <param name="isObeyToHead"></param>
        public static void AliagnShapeRange(PPT.Application app, bool isHori, bool isVert, bool isObeyToHead)
        {
            var pres = app.ActivePresentation;
            var slideRange = GetCurrentSlideRange(app);
            var shapeRange = GetCurrentShapeRange(app);
            if (slideRange == null) return;
            if (shapeRange == null) return;

            var left = GetPresentationWidth(pres) / 2;
            var top = GetPresentationHeight(pres) / 2;

            if (shapeRange.Count >= 2 && isObeyToHead) // 与当前首个图形一致。
            {
                left = shapeRange[1].Left;
                top = shapeRange[1].Top;
            }
            AliagnShape(isHori, isVert, left, top, shapeRange);
        }

        /// <summary>
        /// 对齐。
        /// </summary>
        /// <param name="isHori">是否横向对齐</param>
        /// <param name="isVert">是否纵向对齐</param>
        /// <param name="left">左值</param>
        /// <param name="top">右值</param>
        /// <param name="shapeRange">作用对象。</param>
        public static void AliagnShape(bool isHori, bool isVert, float left, float top, PPT.ShapeRange shapeRange)
        {
            if (isHori)
            {
                foreach (PPT.Shape item in shapeRange)
                {
                    item.Top = top;
                }
            }

            if (isVert)
            {
                foreach (PPT.Shape item in shapeRange)
                {
                    item.Left = left;
                }
            }
        }

        #endregion

        #region 调整尺寸
        /// <summary>
        /// 调整图形的尺寸
        /// </summary>
        /// <param name="app"></param>
        public static void UnifyShape(PPT.Application app, IList<ParaNameValuePair> paralist)
        {
            var shapeRange = GetCurrentShapeRange(app);
            if (shapeRange == null) return;
            var refshp = shapeRange[1];

            for (int i = 2; i <= shapeRange.Count; i++)
            {
                var shp = shapeRange[i];
                //shp.Left = refshp.Left;
                //shp.Top = refshp.Top;
                shp.Width = refshp.Width;
                shp.Height = refshp.Height;
            }

        }
        #endregion

        #region 选择工具

        public static void SelectReverse(PPT.Application app, IList<ParaNameValuePair> paralist)
        {
            var pres = app.ActivePresentation;
            var slideRange = GetCurrentSlideRange(app);
            var shapeRange = GetCurrentShapeRange(app);
            if (slideRange == null) return;
            var shapes = slideRange[1].Shapes;
            if (shapeRange == null)
            {
                shapes.SelectAll();
                return;
            }
            if (shapeRange.Count == shapes.Count)
            {
                app.ActiveWindow.Selection.Unselect();
                return;
            }

            var selectedHashSet = new HashSet<PPT.Shape>();
            var isreplace = Microsoft.Office.Core.MsoTriState.msoTrue;

            foreach (PPT.Shape item in shapeRange)
            {
                selectedHashSet.Add(item);
            }

            foreach (PPT.Shape item in shapes)
            {
                if (selectedHashSet.Contains(item))
                    continue;
                item.Select(isreplace);
                isreplace = Microsoft.Office.Core.MsoTriState.msoFalse;
            }


        }

        public static void SelectByShapeType(PPT.Application app, IList<ParaNameValuePair> paralist)
        {
            SelectShapeByPredicate(app, (paramTuple) =>
            {
                var headShp = paramTuple.Item1;
                var shp = paramTuple.Item2;

                return shp.Type == headShp.Type;
            });
        }


        /// <summary>
        /// 按条件选中图形。
        /// </summary>
        /// <param name="app"></param>
        /// <param name="predicate"></param>
        public static void SelectShapeByPredicate(PPT.Application app, Predicate<Tuple<PPT.Shape, PPT.Shape>> predicate)
        {
            var pres = app.ActivePresentation;
            var slideRange = GetCurrentSlideRange(app);
            var shapeRange = GetCurrentShapeRange(app);
            if (slideRange == null) return;
            if (shapeRange == null) return;

            var slide = slideRange[1];
            var shape = shapeRange[1];
            var shapes = slide.Shapes;

            shape.Select(Microsoft.Office.Core.MsoTriState.msoTrue);

            foreach (PPT.Shape shp in shapes)
            {
                if (predicate(new Tuple<PPT.Shape, PPT.Shape>(shape, shp))) shp.Select(Microsoft.Office.Core.MsoTriState.msoFalse);
            }
        }

        #endregion

        #region 工具

        /// <summary>
        /// 获得演示文稿的宽度。
        /// </summary>
        /// <param name="pres">演示文稿</param>
        /// <returns></returns>
        public static float GetPresentationWidth(PPT.Presentation pres)
        {
            return pres.PageSetup.SlideWidth;
        }

        /// <summary>
        /// 获得演示文稿的高度。
        /// </summary>
        /// <param name="pres">演示文稿</param>
        /// <returns></returns>
        public static float GetPresentationHeight(PPT.Presentation pres)
        {
            return pres.PageSetup.SlideHeight;
        }

        public static PPT.ShapeRange GetCurrentShapeRange(PPT.Application app)
        {
            var selection = app.ActiveWindow.Selection;
            if (selection.Type == PPT.PpSelectionType.ppSelectionShapes) return selection.ShapeRange;
            return null;
        }

        public static PPT.SlideRange GetCurrentSlideRange(PPT.Application app)
        {
            var selection = app.ActiveWindow.Selection;
            try
            {
                return selection.SlideRange;
            }
            catch
            {
                return null;
            }
        }
        #endregion

    }
}
